/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hss01248.dialog.comp;

import com.hss01248.dialog.config.ConfigBean;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.CommonDialog;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import com.hss01248.dialog.ResourceTable;

import java.text.NumberFormat;

public class ProgressDialog extends CommonDialog {
    private Context ctx;
    /**
     * Creates a ProgressDialog with a circular, spinning progress
     * bar. This is the default.
     */
    public static final int STYLE_SPINNER = 0;

    /**
     * Creates a ProgressDialog with a horizontal progress bar.
     */
    public static final int STYLE_HORIZONTAL = 1;

    private ProgressBar mProgress;
    private Text mProgressMessge;
    private Text mMessageView;

    private int mProgressStyle = STYLE_SPINNER;
    private Text mProgressNumber;
    private String mProgressNumberFormat;
    private Text mProgressPercent;
    private NumberFormat mProgressPercentFormat;

    private int mMax;
    private int mProgressVal;
    private String mMessage;
    private boolean mIndeterminate;
    private boolean mHasStarted;
    private EventHandler mViewUpdateHandler;
    private Color processBarColor;

    public ProgressDialog(Context context, ConfigBean bean) {
        super(context);
        initFormats();
        ctx = context;
        mProgressVal = 0;
        setProgressStyle(bean.isProgressHorzontal ? ProgressDialog.STYLE_HORIZONTAL:ProgressDialog.STYLE_SPINNER);
    }

    private void initFormats() {
        mProgressNumberFormat = "%1d/%2d";
        mProgressPercentFormat = NumberFormat.getPercentInstance();
        mProgressPercentFormat.setMaximumFractionDigits(0);
    }

    /**
     * init main view
     */
    public void initMainView() {
        LayoutScatter inflater = LayoutScatter.getInstance(ctx);
        Component view;
        if (mProgressStyle == STYLE_HORIZONTAL) {

            /* Use a separate handler to update the text views as they
             * must be updated on the same thread that created them.
             */
            mViewUpdateHandler = new ProgressBarEventHandler(EventRunner.getMainEventRunner());

            view = inflater.parse(ResourceTable.Layout_progressdialog_h, null, false);
            mProgress = (ProgressBar) view.findComponentById(ResourceTable.Id_progressbarh);
            mProgressMessge = (Text) view.findComponentById(ResourceTable.Id_progress_message);
            mProgressNumber = (Text) view.findComponentById(ResourceTable.Id_progress_number);
            mProgressPercent = (Text) view.findComponentById(ResourceTable.Id_progress_percent);
        } else {
            view = inflater.parse(ResourceTable.Layout_progressdialog, null, false);
            mProgress = (ProgressBar) view.findComponentById(ResourceTable.Id_progressbar);
            mMessageView = (Text) view.findComponentById(ResourceTable.Id_progress_message);
        }
        processBarColor = mProgress.getProgressColor();
        setContentCustomComponent(view);
    }

    /**
     * on dialog create
     */
    @Override
    protected void onCreate() {

        if (mMax > 0) {
            setMax(mMax);
        }
        if (mProgressVal > 0) {
            setProgress(mProgressVal);
        }
        if (mMessage != null) {
            setContentText(mMessage);
        }
        setIndeterminate(mIndeterminate);
        onProgressChanged();
        super.onCreate();
        mProgress.setProgressColor(processBarColor);
    }

    /**
     * on dialog show
     */
    @Override
    public void onShow() {
        super.onShow();
        mHasStarted = true;
        mProgress.setProgressColor(processBarColor);
    }

    /**
     * on dialog destroy
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHasStarted = false;
    }

    /**
     * Sets the current progress.
     *
     * @param value the current progress, a value between 0 and {@link #getMax()}
     *
     * @see ProgressBar#setProgressValue(int)
     */
    public void setProgress(int value) {
        if (mHasStarted) {
            if (!(mIndeterminate && mProgress instanceof RoundProgressBar)) {
                mProgress.setProgressValue(value);
            }
            onProgressChanged();
        } else {
            mProgressVal = value;
        }
    }

    /**
     * Gets the current progress.
     *
     * @return the current progress, a value between 0 and {@link #getMax()}
     */
    public int getProgress() {
        if (mProgress != null) {
            return mProgress.getProgress();
        }
        return mProgressVal;
    }


    /**
     * Gets the maximum allowed progress value. The default value is 100.
     *
     * @return the maximum value
     */
    public int getMax() {
        if (mProgress != null) {
            return mProgress.getMax();
        }
        return mMax;
    }

    /**
     * Sets the maximum allowed progress value.
     */
    public void setMax(int max) {
        if (mProgress != null) {
            mProgress.setMaxValue(max);
            onProgressChanged();
        } else {
            mMax = max;
        }
    }

    /**
     * Change the indeterminate mode for this ProgressDialog. In indeterminate
     * mode, the progress is ignored and the dialog shows an infinite
     * animation instead.
     *
     * <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
     * is always indeterminate and will ignore this setting.</p>
     *
     * @param indeterminate true to enable indeterminate mode, false otherwise
     *
     * @see #setProgressStyle(int)
     */
    public void setIndeterminate(boolean indeterminate) {
        if (mProgressStyle == STYLE_HORIZONTAL) {
            mIndeterminate = indeterminate;
        }
        else
        {
            mIndeterminate = true;
        }
        if (mProgress != null) {
            mProgress.setIndeterminate(mIndeterminate);
        }
    }

    /**
     * Whether this ProgressDialog is in indeterminate mode.
     *
     * @return true if the dialog is in indeterminate mode, false otherwise
     */
    public boolean isIndeterminate() {
        if (mProgress != null) {
            return mProgress.isIndeterminate();
        }
        return mIndeterminate;
    }

    /**
     * set dialog content text
     * @param message text
     * @return diloag
     */
    @Override
    public CommonDialog setContentText(String message) {
        if (mProgress != null) {
            if (mProgressStyle == STYLE_HORIZONTAL) {
                //super.setContentText(message);
                mProgressMessge.setText(message);
            } else {
                mMessageView.setText(message);
            }
        } else {
            mMessage = message;
        }
        return this;
    }

    /**
     * Sets the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
     * {@link #STYLE_HORIZONTAL}. The default is {@link #STYLE_SPINNER}.
     *
     * <p><strong>Note:</strong> A ProgressDialog with style {@link #STYLE_SPINNER}
     * is always indeterminate and will ignore the {@link #setIndeterminate(boolean)
     * indeterminate} setting.</p>
     *
     * @param style the style of this ProgressDialog, either {@link #STYLE_SPINNER} or
     * {@link #STYLE_HORIZONTAL}
     */
    private void setProgressStyle(int style) {
        mProgressStyle = style;
    }

    /**
     * Change the format of the small text showing current and maximum units
     * of progress.  The default is "%1d/%2d".
     * Should not be called during the number is progressing.
     * @param format A string passed to {@link String#format String.format()};
     * use "%1d" for the current number and "%2d" for the maximum.  If null,
     * nothing will be shown.
     */
    public void setProgressNumberFormat(String format) {
        mProgressNumberFormat = format;
        onProgressChanged();
    }

    /**
     * Change the format of the small text showing the percentage of progress.
     * The default is
     * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
     * Should not be called during the number is progressing.
     * @param format An instance of a {@link NumberFormat} to generate the
     * percentage text.  If null, nothing will be shown.
     */
    public void setProgressPercentFormat(NumberFormat format) {
        mProgressPercentFormat = format;
        onProgressChanged();
    }

    private void onProgressChanged() {
        if (mProgressStyle == STYLE_HORIZONTAL) {
            if (mViewUpdateHandler != null && !mViewUpdateHandler.hasInnerEvent(0)) {
                mViewUpdateHandler.sendEvent(0);
            }
        }
    }

    /**
     * Process Bar Event Handler
     */
    class ProgressBarEventHandler extends EventHandler {
        public ProgressBarEventHandler(EventRunner runner)
        {
            super(runner);
        }

        /**
         * process event
         * @param msg message
         */
        @Override
        public void processEvent(InnerEvent msg) {
            super.processEvent(msg);
            if(mProgress !=null&&mProgressNumber !=null&&mProgressPercent !=null)
            {
                /* Update the number and percent */
                int progress = mProgress.getProgress();
                int max = mProgress.getMax();
                if (mProgressNumberFormat != null) {
                    String format = mProgressNumberFormat;
                    mProgressNumber.setText(String.format(format, progress, max));
                } else {
                    mProgressNumber.setText("");
                }
                if (mProgressPercentFormat != null) {
                    double percent = (double) progress / (double) max;
                    mProgressPercent.setText(mProgressPercentFormat.format(percent));
                } else {
                    mProgressPercent.setText("");
                }
            }
        }
    };
}
